import axios, {AxiosError, AxiosResponse} from "axios";
import LoginState from "@/state/loginState";
import UIUtil from "@/lib/UIUtil";
import {ApiResponse} from "@/lib/types";
import {stat} from "fs";


const ajax = axios.create({
    baseURL: '/api',
    timeout: 6000,
    responseType: 'json',
    headers: {"Content-Type": "application/json;charset=UTF-8"},
});


/**
 * 处理ajax异常
 *
 * @param ex axios异常
 * @return 错误提示消息
 */
function handlerAxiosError(ex: AxiosError): string {
    const status = ex.response?.status;
    const data = ex.response?.data
    const message = (data && data.message) || ex.message;

    switch (status){
        // 需要登录 => 弹出登录框
        case 403:
            LoginState.isShowLoginDialog = true;
            return message;

        default:
            UIUtil.messageError(message);
            return message;
    }
}

/**
 * 处理ajax响应值,如果出现错误,会弹出提示
 *
 * @param response  服务器响应
 */
function handleAxiosResponse(response: AxiosResponse<ApiResponse>): ApiResponse {
    const apiResponse = response.data;
    const code = apiResponse.code;
    const message = apiResponse.message;

    if (!code) {
        throw `[${response.config.url}]服务器响应体错误,请检查结构`;
    }

    // 注意这个 200 不是http status  是系统返回的200
    if (code !== '200') {
        UIUtil.messageError(message);
    }

    return apiResponse
}

export default {

    /**
     * 发送 get 请求
     * @param url 请求地址
     * @param params 请求参数
     * @return 通常直接返回数据
     */
    async get(url: string, params: any = {}): Promise<any> {
        try {
            const config = {params};
            const resp = await ajax.get(url, config);
            const data = resp.data;
            // 有code+data 表示是 ApiResponse 对象
            if (data.code && data.data) {
                const apiResponse = handleAxiosResponse(resp);
                return apiResponse.data;
            }
            // 否则是直接返回了数据
            return resp.data;
        } catch (ex) {
            if (axios.isAxiosError(ex)) {
                throw handlerAxiosError(ex);
            }
            throw ex;
        }
    },

    /**
     * 发送 post 请求
     * @param url 请求地址
     * @param data 请求数据
     */
    async post(url: string, data: any = {}): Promise<ApiResponse> {
        try {
            const resp = await ajax.post(url, data);
            return handleAxiosResponse(resp);
        } catch (ex) {
            if (axios.isAxiosError(ex)) {
                throw handlerAxiosError(ex);
            }
            throw ex;
        }
    },

    /**
     * 发送 put 请求
     * @param url 请求地址
     * @param data 请求数据
     */
    async put(url: string, data: any = {}): Promise<ApiResponse> {
        try {
            const resp = await ajax.put(url, data);
            return handleAxiosResponse(resp);
        } catch (ex) {
            if (axios.isAxiosError(ex)) {
                throw handlerAxiosError(ex);
            }
            throw ex;
        }
    },

    /**
     * 发送 delete 请求
     * @param url 请求地址
     * @param params 请求数据
     */
    async delete(url: string, params: any = {}): Promise<ApiResponse> {
        try {
            const config = {params};
            const resp = await ajax.delete(url, config);
            return handleAxiosResponse(resp);
        } catch (ex) {
            if (axios.isAxiosError(ex)) {
                throw handlerAxiosError(ex);
            }
            throw ex;
        }
    },


}